/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
/*
 * bocciawii
 * Copyright (C) Grupo de trabajo ULE 2010 <ulewii@googlegroups.com>
 * 
 * teclado is free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * teclado is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along
 * with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef _SCREEN_LAYOUT_H_
#define _SCREEN_LAYOUT_H_
#include "linked-container.h"

/**
 * @brief Implementación de un "GridLayout" básico
 * 
 * Esta clase se puede ver como un "UnlinkedContainer". Viene a ser
 * precisamente a los LinkedContainer, lo que éstos son a los Elementos.
 * Un padre para objetos de tipo LinkedContainer.
 * 
 * Es uno de los dos super-contenedores ofrecidos con el motor. Similar a un
 * GridLayout de SWT, es un contenedor dividido en filas y columnas.
 * En cada posición del 'grid' se cuelga un LinkedContainer.
 *
 * Este es el contenedor básico para mostrar cualquier elemento en pantalla
 * sin tener que preocuparse por calcular su espacio, o una posición global.
 * Utilizará porcentajes, en función del número de filas y de columnas
 * y de la resolución de pantalla.
 * 
 * Con esto la pantalla se divide en cuadrantes, con los que 
 * se calcula el centro de los mismos, y se hace Pack() a los hijos con esos centros
 * que a su vez calcularán también los centros de sus hijos en su propio Pack();
 * Es un Pack() recursivo, al igual que el dibujado. De ahí que esta sea la clase
 * básica para mostrar cualquier cosa en pantalla.
 */
class ScreenLayout
{
public:
	/**
	 * @brief Nuestro constructor
	 *
	 * Arranca las variables y demás. Ha de tomar como argumentos
	 * un número de filas y columnas > 0
	 *
	 *
	 * @param filas número de filas del layout
	 * @param cols número de columnas del layout
	 */
	ScreenLayout(int filas, int cols);
	virtual ~ScreenLayout();

	/**
	 * @brief 'Colgar' un hijo en el layout
	 *
	 * Asignará a una posición un LinkedContainer
	 *
	 * @param cont El LinkedContainer a añadir
	 * @param x fila en la que colgarlo (de 0 a num_filas-1)
	 * @param y columna en la que colgarlo (de 0 a num_cols-1)
	 */
	void Append(LinkedContainer* cont, int x, int y);
	
	/**
	 * @brief Buscar un <code>Elemento</code>
	 *
	 * Buscará un <code>Elemento</code> (Barra y Mensajes) de entre todos los
	 * LinkedContainer que albergue
	 *
	 *
	 * @param id identificador del elemento a buscar
	 * @return El elemento, si se ha encontrado, NULL en otro caso
	 */
	Elemento* GetElemByID(std::string id);

	/**
	 * @brief Setter para la visibilidad del container
	 *
	 * Asignar la visibilidad del LinkedContainer
	 *
	 *
	 * @param visible 1 dibujar, 0 no dibujar
	 */
	inline void SetVisible(int visible)
	{	_visible = visible;   }

	/**
	 * @brief Getter para la visibilidad
	 *
	 * 
	 * Determinar la visibilidad del ScreenLayout
	 *
	 * @return 1 si es visible, 0 de lo contrario
	 */
	inline int GetVisible()
	{	return _visible;   }

	/**
	 * @brief Empaquetado para ScreenLayout y sus hijos
	 *
	 * A partir simplemente de la resolución de la pantalla, este procedimiento
	 * dividirá la pantalla en cuadrantes, de los que calculará su centro, y si
	 * en alguno de estos cuadrantes existiera un LinkedContainer, lo empaquetaría
	 * utilizándolo. Llamando a este procedimiento se garantiza que todos los
	 * elementos contenidos tanto en el ScreenLayout como en los LinkedContainer
	 * que poseyera directamente, los Elementos contenidos en estos últimos también
	 * serían empaquetados.
	 *
	 *
	 * @param pantalla_x El ancho de la pantalla
	 * @param pantalla_y El alto de la pantalla
	 */
	void Pack(int pantalla_x, int pantalla_y);
	
	/**
	 * @brief Dibujado del ScreenLayout
	 *
	 * Este procedimiento desencadena el dibujado de todos los LinkedContainer 
	 * en el grid, y estos a su vez, desencadena el dibujado de los Elementos
	 *
	 */
	void Dibujar();
	
	/**
	 * @brief Crear un entorno de dibujo bidimensional
	 *
	 * Se crea el entorno que permitirá dibujar los elementos planos, esto es,
	 * una matriz que mapea directamente a píxel.
	 * Este entorno es creado de manera que la esquina superior izquierda es el
	 * el punto (0,0). Se hace así para que coincida con SDL, y sobre todo, con
	 * las cargas de imágenes de SDL_image.h
	 *
	 */
	void SetOrtho();
	
	/**
	 * @brief Volver al estado de dibujado normal
	 *
	 * Se vuelve al estado anterior en las matrices de OpenGL para proseguir
	 * con el dibujado tridimensional.
	 */
	void UnsetOrtho();

protected:
	/// El número de filas del container
	int _numFilas;
	/// El número de columnas del container
	int _numCols;

	/// El ancho de la pantalla
	int _pantX;
	/// El alto de la pantalla
	int _pantY;

	/// Si el supercontenedor es visible
	int _visible;

	/// Hijos
	LinkedContainer* conts[10][10];

private:
	

};

#endif // _SCREEN_LAYOUT_H_
